
#include<iostream>
#include<unistd.h>  
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include<cstring>
#include<string>
void Usage(const std::string &proc)
{
    std::cout << "\n\rUsage: " << proc << " serverip serverport\n"
              << std::endl;
}


// ./tcpclient serverip serverport
int main(int argc, char *argv[])
{

  if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
            //创建tcp套接字 
        int sockfd =  socket(AF_INET , SOCK_STREAM , 0) ;
    if( sockfd < 0) 
    {
        std::cerr <<"socket error" <<std::endl;
        return 1 ;
    }

 uint16_t  serverport  = std::stoi(argv[2] )   ;
 std::string  serverip= argv[1];

    struct sockaddr_in  server ;
    memset(&server , 0 ,sizeof(server));
    server.sin_family =AF_INET; 
    server.sin_port = htons(serverport ) ;

    inet_pton(AF_INET,serverip.c_str() , & (server.sin_addr ));//将一个点分十进制的IP地址字符串转换为网络字节顺序的数值形式
    //tcp的客户端是需要bind端口号，但是不需要显示的bind端口号 ,由操作系统随机选择端口号
    //客户端发起connect时，进行自动随机bind
        int n = connect(sockfd , (  struct sockaddr *) &server  , sizeof( server)) ;
       if (n < 0)
            {
                std::cerr << "connect error... "  << std::endl;
            return 2 ;
            }
      
      std::string message ;
      
  while (true)
    {
         
          std::cout<<"Please enter #" <<std::endl;
        getline(std::cin, message) ;
       //从键盘文件中写入数据 
       write(sockfd, message.c_str() , sizeof(message));
     char inbuffer [4096] ;    
        read(sockfd,inbuffer,sizeof(inbuffer));
        if(n>0) 
        {
            inbuffer[n] =0 ;//把inbuffer当成字符串处理
           std:: cout<<inbuffer<<std::endl;
        }
    }
    close (sockfd) ;
    return 0 ;
}